﻿using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;

namespace BingImages
{
    public class StreamBing
    {
        private const int SPI_SETDESKWALLPAPER = 20;
        private const int SPIF_UPDATEINIFILE = 0x01;
        private const int SPIF_SENDWININICHANGE = 0x02;

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni);

        private Folder _folder;
        private string _lastFile;
        private string _lastListFile;
        private Timer _timer;
        private string _wallpaperScroll;
        private List<string> listDate = null;
        private List<string> listURL = null;

        public StreamBing(string wallpaperScroll)
        {
            this._folder = new Folder();
            this._lastFile = DateTime.Now.ToString("yyyy-MM-dd") + ".png";
            this._lastListFile = "";
            this._timer = new Timer();
            this._wallpaperScroll = wallpaperScroll;
        }

        private Stream getStream(string url)
        {
            Stream resStream = null;

            try
            {
                var request = (HttpWebRequest)WebRequest.Create(url);
                var response = (HttpWebResponse)request.GetResponse();
                resStream = response.GetResponseStream();
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }

            return resStream;
        }

        public void getPicture()
        {                
            this._timer.Tick += new EventHandler(timer_Tick);
            this._timer.Interval = 15000;
            this._timer.Start();
            this.processTick();
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            this.processTick();
        }

        private void processTick()
        {
            try
            {
                if (this._lastListFile == this._lastFile)
                {
                    this.endProcessTick(this._lastListFile);
                }
                else
                {
                    string pageSource = "";
                    string dateValue = "";
                    DateTime parse;
                    string urlValue = "";
                    this.listDate = new List<string>();
                    this.listURL = new List<string>();
                    int indexURL = 0;
                    string combinePath = "";

                    using (StreamReader sr = new StreamReader(getStream("http://www.bing.com/hpimagearchive.aspx?format=xml&idx=0&n=8&mbl=1&mkt=en-ww")))
                    {
                        pageSource = sr.ReadToEnd();
                    }

                    using (XmlReader reader = XmlReader.Create(new StringReader(pageSource)))
                    {
                        while (reader.Read())
                        {
                            if (reader.NodeType == XmlNodeType.Element)
                            {
                                if (reader.Name == "startdate")
                                {
                                    if (reader.Read())
                                    {
                                        if (reader.NodeType == XmlNodeType.Text)
                                        {
                                            dateValue = reader.Value;
                                            parse = DateTime.ParseExact(dateValue, "yyyyMMdd", null);
                                            dateValue = parse.Year + "-" + parse.Month.ToString("d2") + "-" + parse.Day.ToString("d2") + ".png";
                                            listDate.Add(dateValue);
                                        }
                                    }
                                }

                                if (reader.Name == "url")
                                {
                                    if (reader.Read())
                                    {
                                        if (reader.NodeType == XmlNodeType.Text)
                                        {
                                            urlValue = reader.Value;
                                            urlValue = "http://bing.com" + urlValue.Replace("1366x768", "1920x1200");
                                            listURL.Add(urlValue);
                                        }
                                    }
                                }
                            }
                        }
                    }

                    foreach (string url in listURL)
                    {
                        indexURL = listURL.IndexOf(url);
                        combinePath = Path.Combine(this._folder.last, listDate[indexURL]);

                        if (!File.Exists(combinePath))
                        {
                            using (var image = Image.FromStream(this.getStream(url)))
                            {
                                var newWidth = (int)(image.Width);
                                var newHeight = (int)(image.Height);
                                var thumbnailImg = new Bitmap(newWidth, newHeight);
                                var thumbGraph = Graphics.FromImage(thumbnailImg);
                                thumbGraph.CompositingQuality = CompositingQuality.HighQuality;
                                thumbGraph.SmoothingMode = SmoothingMode.HighQuality;
                                thumbGraph.InterpolationMode = InterpolationMode.HighQualityBicubic;
                                var imageRectangle = new Rectangle(0, 0, newWidth, newHeight);
                                thumbGraph.DrawImage(image, imageRectangle);
                                thumbnailImg.Save(combinePath, image.RawFormat);
                            }
                        }
                    }

                    this._lastListFile = listDate.First();

                    if (this._lastListFile == this._lastFile)
                    {
                        this.endProcessTick(this._lastListFile);
                    }
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }

        private void endProcessTick(string lastFile)
        {
            this._timer.Stop();
            this._timer.Dispose();

            FileInfo[] files = null;

            if (string.IsNullOrEmpty(this._wallpaperScroll))
            {
                this._wallpaperScroll = "False";
            }

            if (this._wallpaperScroll == "False")
            {
                Image picture = null;
                string tempPath = "";
                RegistryKey key = null;

                picture = Image.FromFile(Path.Combine(this._folder.last, lastFile));
                tempPath = Path.Combine(Path.GetTempPath(), "wallpaper.bmp");
                picture.Save(tempPath, System.Drawing.Imaging.ImageFormat.Bmp);

                key = Registry.CurrentUser.OpenSubKey(@"Control Panel\Desktop", true);
                key.SetValue(@"WallpaperStyle", 2.ToString());
                key.SetValue(@"TileWallpaper", 0.ToString());

                SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, tempPath, SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
                picture.Dispose();
            }

            files = this._folder.getFiles("last", "*.png");

            foreach(FileInfo file in files)
            {
                if(!this.listDate.Contains(file.Name))
                {
                    file.Delete();
                }
            }
        }
    }
}
